using UnityEngine;
using System.Collections;

public class MarbleCamera : MonoBehaviour {

	public static MarbleCamera Instance;
    public Transform target;
	public float pitchAngle = 0.5f;
    public float zDistance = 5.0f;
    public float dampSpeed = 2;
	public float angle = 0.0f;
	public float targetAngle = 0.0f;
	public bool freeFly = false;
	public Vector3 touchGameOverPos;
    public Vector3 up;
    private float lastLeftTurn;
    private float lastRightTurn;
    
    public Vector3 strafe;

	void Awake()
    {
        lastLeftTurn = Time.time;
        lastRightTurn = Time.time;
        up = new Vector3(0, 1, 0);
        strafe = new Vector3(1, 0, 0);
		touchGameOverPos = new Vector3(0,0,0);
        Instance = this; 
	}
	
    void Update ()
    {
		
        const float rotPause = 0.2f;
		
        if (Input.GetAxisRaw("Camera") != 0)
        {
			
            if (Input.GetKeyDown("left") && (Time.time - lastLeftTurn) > rotPause)
            {
				Debug.Log(gameObject.name);
                targetAngle -= Mathf.PI * 0.5f;
                lastLeftTurn = Time.time;
            }
            if (Input.GetKeyDown("right") && (Time.time - lastRightTurn) > rotPause)
            {
                targetAngle += Mathf.PI * 0.5f;
                lastRightTurn = Time.time;
            }
        }
        
        if (Input.GetAxisRaw("Horizontal") != 0)
        {
            if (Input.GetKeyDown("left shift") || Input.GetKeyDown("right shift"))
            {
                if (Input.GetAxisRaw("Horizontal") > 0)
                {
                    if ((Time.time - lastRightTurn) > rotPause)
                    {
                        targetAngle += Mathf.PI * 0.5f;
                        lastRightTurn = Time.time;
                    }
                }
                else
                {
                    if ((Time.time - lastLeftTurn) > rotPause)
                    {
                        targetAngle -= Mathf.PI * 0.5f;
                        lastLeftTurn = Time.time;
                    }
                }
            }
        }
		
		float deltaAngle = targetAngle - angle;
		float velocity = 10.0f;
		
		if (deltaAngle > 0.0f)
		{
			if (velocity * Time.deltaTime > deltaAngle)
			{
				angle += deltaAngle;
			}
			else
			{
				angle += velocity*Time.deltaTime;
			}
		}
		else
		{
			if (velocity * Time.deltaTime > -deltaAngle)
			{
				angle += deltaAngle;
			}
			else
			{
				angle += -velocity*Time.deltaTime;
			}
			
		}
		Vector3 targetPos = target.position;
        //if (targetPos.y < 0.0f)
        //{
        //    targetPos.y = 0.0f;
        //}

        float height = zDistance * Mathf.Sin(pitchAngle);
        float length = zDistance * Mathf.Cos(pitchAngle);
        Vector3 fwd = Vector3.Cross(up, strafe);
        fwd.Normalize();
        Vector3 delta = up * height + fwd * length;

        Vector3 newPos = targetPos + delta;// new Vector3(zDistance * Mathf.Sin(angle) * Mathf.Cos(pitchAngle), zDistance * Mathf.Sin(pitchAngle), zDistance * Mathf.Cos(angle) * Mathf.Cos(pitchAngle));
        transform.position = newPos;//Vector3.Lerp(transform.position, newPos, Time.deltaTime*dampSpeed);
		
        if (freeFly)
		{

            Vector3 targetPos3d = target.position;
            Vector2 targetPos2d = new Vector2(targetPos3d.x, targetPos3d.z);
            Vector2 touchPos2d = new Vector2(touchGameOverPos.x, touchGameOverPos.z);

            const float minDist = 0.2f;
            if ((touchPos2d - targetPos2d).magnitude < minDist)
            {
                Vector2 diff = targetPos2d - touchPos2d;
                diff.Normalize();
                targetPos2d = touchPos2d + diff * minDist;

                targetPos3d.x = targetPos2d.x;
                targetPos3d.z = targetPos2d.y;
            }
            
            Vector3 targetDir = targetPos3d - touchGameOverPos;
            Quaternion targetRotation = Quaternion.LookRotation(targetDir, up);
			
            transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, 2.0f * Time.deltaTime);
			
			targetDir.Normalize();
			
			Vector3 dir2 = transform.rotation * Quaternion.Inverse(targetRotation) * targetDir;
			dir2.Normalize();
			
			transform.position = touchGameOverPos - dir2 * zDistance;
        }
        else
        {
            Vector3 relativePos = target.position - transform.position;
            Quaternion rotation = Quaternion.LookRotation(relativePos, up);
            transform.rotation = rotation;
        }
	}
}
